home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / Include / bf.h < prev    next >
C/C++ Source or Header  |  1990-12-08  |  14KB  |  575 lines

  1. /*
  2.  * bf.h --
  3.  *
  4.  *    Macros to manipulate bits in an array of bytes, shorts, or words,
  5.  *    simulating the effect of bit fields.
  6.  *
  7.  * Copyright 1990 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  *
  16.  * $Header: /sprite/src/kernel/utils/RCS/bf.h,v 1.1 90/10/01 21:40:51 jhh Exp $ SPRITE (Berkeley)
  17.  */
  18.  
  19. #ifndef _BF
  20. #define _BF
  21.  
  22. /*
  23.  * There are a number of formulas that are used to compute which bits
  24.  * within the array are to be manipulated. The following definitions
  25.  * and formulas are used throughout the bf macro package. In the 
  26.  * definitions "left" refers to lower addresses when it refers to array
  27.  * elements, and to the high order bit when it refers to bits within a
  28.  * byte (element).
  29.  *
  30.  *    d = left offset of bit field within the array, in bits.
  31.  *    s = size of the bit field, in bits.
  32.  *    u = size of array elements, in bits.
  33.  *    v = value to assign to or test the bit field with.
  34.  *    x = index of current element of array that is being manipulated,
  35.  *        where x = 0 is the index for the left-most element that
  36.  *        contains part of the bit field.
  37.  *    Dx = left offset of bit field within array element x.
  38.  *    Sx = size of bit field in array element x.
  39.  *    Rx = number of bits in bit field that are to the right of element
  40.  *        x.
  41.  *    Qx = number of bits in element x that are to the right of the
  42.  *        bit field.
  43.  *    Vx = the value of v associated with the bit field within element
  44.  *        x.
  45.  *    Ix = index of element x within the entire array of elements.
  46.  *    Zx = the value of the bit field within element x.
  47.  *
  48.  * For example, consider the following array of bytes, where '|' denotes
  49.  * byte boundaries, '#' denotes the bits of the bit field, and '_' denotes
  50.  * bits that are not in the bit field:
  51.  *
  52.  *    |________|____####|##______|     (high memory ->)
  53.  *
  54.  * which contains the following values:
  55.  *
  56.  *    |00000000|00001111|11000000|    (binary)
  57.  *
  58.  * Further more let v (the value we want to assign to the bit field) be
  59.  * 101010 binary.  Then we have the following for the variables.  All
  60.  * values are decimal except where noted.
  61.  *    
  62.  *    d = 12
  63.  *    s = 6
  64.  *    u = 8
  65.  *    v = 101010 (binary)
  66.  *    D0 = 4
  67.  *    D1 = 0
  68.  *    S0 = 4
  69.  *    S1 = 2
  70.  *    R0 = 2
  71.  *    R1 = 0
  72.  *    Q0 = 0
  73.  *    Q1 = 6
  74.  *    V0 = 1010 (binary)
  75.  *    V1 = 10000000 (binary)
  76.  *    I0 = 1
  77.  *    I2 = 2
  78.  *    Z0 = 1111 (binary)
  79.  *    Z1 = 11 (binary)
  80.  *
  81.  * The values for d, s, u, and v, are dependent on the format of the
  82.  * bit field.  The values of the other variables can be computed from
  83.  * the following equations.
  84.  *
  85.  *     D0 = d % u
  86.  *    D1, D2, ... = 0
  87.  *    Sx = min(u - Dx, s - (S0 + S1 + ... + S(x-1)))
  88.  *    Qx = u - (Dx + Sx)
  89.  *    Rx = s - (S0 + S1 + ... + Sx)
  90.  *    Vx = ((v >> Rx) & mask(Sx)) << Qx
  91.  *    Zx = array[Ix] & Vx  (v = the biggest mask in this case)
  92.  *
  93.  * where
  94.  *    min(a,b) computes the minimum of a and b
  95.  *    mask(k) produces a number consisting of x bits set to 1
  96.  *    % is the remainder function.
  97.  */
  98.  
  99.  
  100. /*
  101.  *----------------------------------------------------------------------
  102.  *
  103.  * BfMin --
  104.  *
  105.  *    Compute the minimum of two numbers.
  106.  *
  107.  * Results:
  108.  *    The minimum of the two parameters.
  109.  *
  110.  * Side effects:
  111.  *    None.
  112.  *
  113.  *----------------------------------------------------------------------
  114.  */
  115.  
  116. #define BfMin(a, b)    ((a) < (b) ? (a) : (b))
  117.  
  118.  
  119. /*
  120.  *----------------------------------------------------------------------
  121.  *
  122.  * BfMask --
  123.  *
  124.  *    Creates a mask (all bits are 1) with the number of bits indicated
  125.  *    by the size parameter.
  126.  *
  127.  * Results:
  128.  *    The mask value.
  129.  *
  130.  * Side effects:
  131.  *    None.
  132.  *
  133.  *----------------------------------------------------------------------
  134.  */
  135.  
  136. #define BfMask(size)   ((1 << (size)) - 1)
  137.  
  138.  
  139. /*
  140.  *----------------------------------------------------------------------
  141.  *
  142.  * BfDx --
  143.  *
  144.  *    Computes the value Dx
  145.  *
  146.  * Results:
  147.  *    Dx
  148.  *
  149.  * Side effects:
  150.  *    None.
  151.  *
  152.  *----------------------------------------------------------------------
  153.  */
  154.  
  155. #define BfDx(u, x, d)  (((x) == 0) ? ((d) % (u)) : 0)
  156.  
  157.  
  158. /*
  159.  *----------------------------------------------------------------------
  160.  *
  161.  * BfS0, BfS1, BfS2, BfS3, BfS4 --
  162.  *
  163.  *    Computes the values S0, S1, S2, S3, and S4.
  164.  *
  165.  * Results:
  166.  *    S0 or S1 or S2 or S3 or S4.
  167.  *
  168.  * Side effects:
  169.  *    None.
  170.  *
  171.  *----------------------------------------------------------------------
  172.  */
  173.  
  174. #define BfS0(u, d, s)     (BfMin(u - BfDx(u, 0, d), s))
  175.  
  176. #define BfS1(u, d, s)     (BfMin(u - BfDx(u, 1, d), (s) - BfSumS0(u, d, s)))
  177.  
  178. #define BfS2(u, d, s)     (BfMin(u - BfDx(u, 2, d), (s) - BfSumS1(u, d, s)))
  179.  
  180. #define BfS3(u, d, s)     (BfMin(u - BfDx(u, 3, d), (s) - BfSumS2(u, d, s)))
  181.  
  182. #define BfS4(u, d, s)     (BfMin(u - BfDx(u, 4, d), (s) - BfSumS3(u, d, s)))
  183.  
  184. /*
  185.  *----------------------------------------------------------------------
  186.  *
  187.  * BfByteSx, BfHalfwordSx, BfWordSx --
  188.  *
  189.  *    Computes Sx. There are three routines for the three possible
  190.  *    values of u.
  191.  *
  192.  * Results:
  193.  *    Sx.
  194.  *
  195.  * Side effects:
  196.  *    None.
  197.  *
  198.  *----------------------------------------------------------------------
  199.  */
  200.  
  201. #define BfByteSx(x, d, s)     \
  202.     (((x) == 0) ? BfS0(8, d, s) : (((x) == 1) ? BfS1(8, d, s) : BfS2(8, d, s)))
  203.  
  204. #define BfHalfwordSx(x, d, s)     \
  205.     (((x) == 0) ? BfS0(16, d, s) : BfS1(16, d, s))
  206.  
  207. #define BfWordSx(x, d, s)  \
  208.     (((x) == 0) ? BfS0(32, d, s) : BfS1(32, d, s))
  209.  
  210.  
  211. /*
  212.  *----------------------------------------------------------------------
  213.  *
  214.  * BfSumS0, BfSumS1, BfSumS2, BfSumS3,  BfSumS4 --
  215.  *
  216.  *    Computes S0 + S1 + ... SN for some N.
  217.  *
  218.  * Results:
  219.  *    The sum from 0 to N of Si.
  220.  *
  221.  * Side effects:
  222.  *    None.
  223.  *
  224.  *----------------------------------------------------------------------
  225.  */
  226.  
  227.  
  228. #define BfSumS0(u, d, s)  (BfS0(u, d, s))
  229.  
  230.  
  231. #define BfSumS1(u, d, s)  (BfS0(u, d, s) + BfS1(u, d, s))
  232.  
  233.  
  234. #define BfSumS2(u, d, s)  (BfSumS1(u, d, s) + BfS2(u, d, s))
  235.  
  236.  
  237. #define BfSumS3(u, d, s)  (BfSumS2(u, d, s) + BfS3(u, d, s))
  238.  
  239.  
  240. #define BfSumS4(u, d, s)  (BfSumS3(u, d, s) + BfS4(u, d, s))
  241.  
  242.  
  243. /*
  244.  *----------------------------------------------------------------------
  245.  *
  246.  * BfSumByteSx, BfSumHalfwordSx, BfSumWordSx --
  247.  *
  248.  *    Computes the sum of S0 + S1 + ... + Sx.  There is one routine for 
  249.  *    each value of u.
  250.  *
  251.  * Results:
  252.  *    The sum.
  253.  *
  254.  * Side effects:
  255.  *    None.
  256.  *
  257.  *----------------------------------------------------------------------
  258.  */
  259.  
  260. #define BfSumByteSx(x, d, s) \
  261.     (((x) == 0) ? BfSumS0(8, d, s) : (((x) == 1) ? BfSumS1(8, d, s) : \
  262.     BfSumS2(8, d, s)))
  263.  
  264.  
  265. #define BfSumHalfwordSx(x, d, s) \
  266.     (((x) == 0) ? BfSumS0(16, d, s) : BfSumS1(16, d, s))
  267.  
  268.  
  269. #define BfSumWordSx(x, d, s)  \
  270.     (((x) == 0) ? BfSumS0(32, d, s) : BfSumS1(32, d, s))
  271.  
  272.  
  273. /*
  274.  *----------------------------------------------------------------------
  275.  *
  276.  *  BfByteRx, BfHalfwordRx, BfWordRx--
  277.  *
  278.  *    Computes Rx.
  279.  *
  280.  * Results:
  281.  *    Rx
  282.  *
  283.  * Side effects:
  284.  *    None.
  285.  *
  286.  *----------------------------------------------------------------------
  287.  */
  288.  
  289. #define BfByteRx(x, d, s)   ((s) - BfSumByteSx(x, d, s))
  290. #define BfHalfwordRx(x, d, s)   ((s) - BfSumHalfwordSx(x, d, s))
  291. #define BfWordRx(x, d, s)   ((s) - BfSumWordSx(x, d, s))
  292.  
  293.  
  294. /*
  295.  *----------------------------------------------------------------------
  296.  *
  297.  * BfByteQx, BfHalfwordQx, BfWordQx --
  298.  *
  299.  *    Computes Qx.
  300.  *
  301.  * Results:
  302.  *    Qx.
  303.  *
  304.  * Side effects:
  305.  *    None.
  306.  *
  307.  *----------------------------------------------------------------------
  308.  */
  309.  
  310. #define BfByteQx(x, d, s) (8 - (BfDx(8, x, d) + BfByteSx(x, d, s)))
  311. #define BfHalfwordQx(x, d, s) (16 - (BfDx(16, x, d) + BfHalfwordSx(x, d, s)))
  312. #define BfWordQx(x, d, s) (32 - (BfDx(32, x, d) + BfWordSx(x, d, s)))
  313.  
  314.  
  315. /*
  316.  *----------------------------------------------------------------------
  317.  *
  318.  * BfByteVx, BfHalfwordVx, BfWordVx --
  319.  *
  320.  *    Computes Vx
  321.  *
  322.  * Results:
  323.  *    Vx.
  324.  *
  325.  * Side effects:
  326.  *    None.
  327.  *
  328.  *----------------------------------------------------------------------
  329.  */
  330.  
  331. #define BfByteVx(x, d, s, v) \
  332.     ((((v) >> BfByteRx(x, d, s)) & BfMask(BfByteSx(x, d, s))) << \
  333.     BfByteQx(x, d, s))
  334.  
  335. #define BfHalfwordVx(x, d, s, v) \
  336.     ((((v) >> BfHalfwordRx(x, d, s)) & BfMask(BfHalfwordSx(x, d, s))) << \
  337.     BfHalfwordQx(x, d, s))
  338.  
  339. #define BfWordVx(x, d, s, v) \
  340.     ((((v) >> BfWordRx(x, d, s)) & BfMask(BfWordSx(x, d, s))) << \
  341.     BfWordQx(x, d, s))
  342.  
  343.  
  344. /*
  345.  *----------------------------------------------------------------------
  346.  *
  347.  * BfIx --
  348.  *
  349.  *    Computes Ix
  350.  *
  351.  * Results:
  352.  *    Ix
  353.  *
  354.  * Side effects:
  355.  *    None.
  356.  *
  357.  *----------------------------------------------------------------------
  358.  */
  359.  
  360. #define BfIx(u, x, d) (((d) / (u)) + (x))
  361.  
  362.  
  363. /*
  364.  *----------------------------------------------------------------------
  365.  *
  366.  * BfByteZx, BfHalfwordZx, BfWordZx --
  367.  *
  368.  *    Computes Zx.
  369.  *
  370.  * Results:
  371.  *    Zx.
  372.  *
  373.  * Side effects:
  374.  *    None.
  375.  *
  376.  *----------------------------------------------------------------------
  377.  */
  378.  
  379. #define BfByteZx(ptr, x, d, s) \
  380.     ((ptr)[BfIx(8, x, d)] & BfByteVx(x, d, s, 0xffffffff))
  381.  
  382. #define BfHalfwordZx(ptr, x, d, s) \
  383.     ((ptr)[BfIx(16, x, d)] & BfHalfwordVx(x, d, s, 0xffffffff))
  384.  
  385. #define BfWordZx(ptr, x, d, s) \
  386.     ((ptr)[BfIx(32, x, d)] & BfWordVx(x, d, s, 0xffffffff))
  387.  
  388.  
  389. /*
  390.  *----------------------------------------------------------------------
  391.  *
  392.  * BfByteSetx, BfHalfwordSetx, BfWordSetx --
  393.  *
  394.  *    Stores the value Vx into the xth element containing the bit field.
  395.  *
  396.  * Results:
  397.  *    None.
  398.  *
  399.  * Side effects:
  400.  *    None.
  401.  *
  402.  *----------------------------------------------------------------------
  403.  */
  404.  
  405. #define BfByteSetx(ptr, x, d, s, v)  {                    \
  406.     if ((v) != BfMask(s)) {                        \
  407.     (ptr)[BfIx(8, x, d)] &= ~BfByteVx(x, d, s, 0xffffffff);     \
  408.     }                                    \
  409.     (ptr)[BfIx(8, x, d)] |= BfByteVx(x, d, s, v);             \
  410. }
  411.  
  412. #define BfHalfwordSetx(ptr, x, d, s, v)  {                \
  413.     if ((v) != BfMask(s)) {                        \
  414.     (ptr)[BfIx(16, x, d)] &= ~BfHalfwordVx(x, d, s, 0xffffffff);     \
  415.     }                                    \
  416.     (ptr)[BfIx(16, x, d)] |= BfHalfwordVx(x, d, s, v);            \
  417. }
  418.  
  419. #define BfWordSetx(ptr, x, d, s, v)  {                    \
  420.     if ((v) != BfMask(s)) {                        \
  421.     ((ptr)[BfIx(32, x, d)]) &= ~BfWordVx(x, d, s, 0xffffffff);     \
  422.     }                                    \
  423.     ((ptr)[BfIx(32, x, d)]) |= BfWordVx(x, d, s, v);             \
  424. }
  425.  
  426.  
  427. /*
  428.  *----------------------------------------------------------------------
  429.  *
  430.  * BfByteTestx, BfHalfwordTestx, BfWordTestx --
  431.  *
  432.  *    Tests the xth element containing the bit field against the value
  433.  *    Vx.
  434.  *
  435.  * Results:
  436.  *    1 if Zx == Vx, 0 otherwise
  437.  *
  438.  * Side effects:
  439.  *    None.
  440.  *
  441.  *----------------------------------------------------------------------
  442.  */
  443.  
  444.  
  445. #define BfByteTestx(ptr, x, d, s, v) \
  446.     (BfByteZx(ptr, x, d, s) == BfByteVx(x, d, s, v))
  447.  
  448. #define BfHalfwordTestx(ptr, x, d, s, v) \
  449.     (BfHalfwordZx(ptr, x, d, s) == BfHalfwordVx(x, d, s, v))
  450.  
  451. #define BfWordTestx(ptr, x, d, s, v) \
  452.     (BfWordZx(ptr, x, d, s) == BfWordVx(x, d, s, v))
  453.  
  454.  
  455. /*
  456.  *----------------------------------------------------------------------
  457.  *
  458.  * Bf_ByteSet, Bf_HalfwordSet, Bf_WordSet --
  459.  *
  460.  *    Set the bit field defined by ptr, d and s with the value v.
  461.  *
  462.  * Results:
  463.  *    None.
  464.  *
  465.  * Side effects:
  466.  *    None.
  467.  *
  468.  *----------------------------------------------------------------------
  469.  */
  470.  
  471. #define Bf_ByteSet(ptr, d, s, v)  {                \
  472.     BfByteSetx(ptr, 0, d, s, v);                \
  473.     if (BfByteRx(0, d, s) > 0) {                \
  474.     BfByteSetx(ptr, 1, d, s, v);                \
  475.     if (BfByteRx(1, d, s) > 0) {                \
  476.         BfByteSetx(ptr, 2, d, s, v);            \
  477.     }                            \
  478.     }                                \
  479. }
  480.  
  481. #define Bf_HalfwordSet(ptr, d, s, v)  {                \
  482.     BfHalfwordSetx(ptr, 0, d, s, v);                \
  483.     if (BfHalfwordRx(0, d, s) > 0) {                \
  484.     BfHalfwordSetx(ptr, 1, d, s, v);            \
  485.     }                                \
  486. }
  487.  
  488. #define Bf_WordSet(ptr, d, s, v)  {                \
  489.     BfWordSetx(ptr, 0, d, s, v);                \
  490.     if (BfWordRx(0, d, s) > 0) {                \
  491.     BfWordSetx(ptr, 1, d, s, v);                \
  492.     }                                \
  493. }
  494.  
  495.  
  496. /*
  497.  *----------------------------------------------------------------------
  498.  *
  499.  * Bf_ByteTest, Bf_HalfwordTest, Bf_WordTest --
  500.  *
  501.  *    Compare the bitfield defined by ptr, d, and s with the value v.
  502.  *
  503.  * Results:
  504.  *    1 if the value in the bitfield equals v, 0 otherwise
  505.  *
  506.  * Side effects:
  507.  *    None.
  508.  *
  509.  *----------------------------------------------------------------------
  510.  */
  511.  
  512. #define Bf_ByteTest(ptr, d, s, v)                 \
  513.     ((BfByteRx(0, d, s) <= 0) ?                 \
  514.     (BfByteTestx(ptr, 0, d, s, v)) :             \
  515.     ((BfByteRx(1, d, s) <= 0) ?                \
  516.         (BfByteTestx(ptr, 0, d, s, v) &&            \
  517.         BfByteTestx(ptr, 1, d, s, v)) :            \
  518.         (BfByteTestx(ptr, 0, d, s, v) &&            \
  519.         BfByteTestx(ptr, 1, d, s, v) &&            \
  520.         BfByteTestx(ptr, 2, d, s, v))))
  521.  
  522. #define Bf_HalfwordTest(ptr, d, s, v)                 \
  523.     ((BfHalfwordRx(0, d, s) <= 0) ?                 \
  524.     (BfHalfwordTestx(ptr, 0, d, s, v)) :            \
  525.     (BfHalfwordTestx(ptr, 0, d, s, v) &&            \
  526.     BfHalfwordTestx(ptr, 1, d, s, v)))
  527.  
  528. #define Bf_WordTest(ptr, d, s, v)                 \
  529.     ((BfWordRx(0, d, s) <= 0) ?                 \
  530.     (BfWordTestx(ptr, 0, d, s, v)) :            \
  531.     (BfWordTestx(ptr, 0, d, s, v) &&            \
  532.     BfWordTestx(ptr, 1, d, s, v)))
  533.  
  534.  
  535.  
  536. /*
  537.  *----------------------------------------------------------------------
  538.  *
  539.  * Bf_ByteGet, Bf_HalfwordGet, Bf_WordGet --
  540.  *
  541.  *    Returns the value in the bitfield defined by ptr, d and s.
  542.  *
  543.  * Results:
  544.  *    The value of the bitfield.
  545.  *
  546.  * Side effects:
  547.  *    None.
  548.  *
  549.  *----------------------------------------------------------------------
  550.  */
  551.  
  552. #define Bf_ByteGet(ptr, d, s)                     \
  553.     ((BfByteRx(0, d, s) == 0) ?                 \
  554.     (BfByteZx(ptr, 0, d, s) >> BfByteQx(0, d, s)) :     \
  555.     ((BfByteZx(ptr, 0, d, s) << BfByteRx(0, d, s)) |    \
  556.     ((BfByteRx(1, d, s) == 0) ?                   \
  557.         (BfByteZx(ptr, 1, d, s) >> BfByteQx(1, d, s)) :     \
  558.         ((BfByteZx(ptr, 1, d, s) << BfByteRx(1, d, s)) |    \
  559.         (BfByteZx(ptr, 2, d, s) >> BfByteQx(2, d, s))))))
  560.  
  561. #define Bf_HalfwordGet(ptr, d, s)                     \
  562.     ((BfHalfwordRx(0, d, s) == 0) ?                     \
  563.     (BfHalfwordZx(ptr, 0, d, s) >> BfHalfwordQx(0, d, s)) :     \
  564.     ((BfHalfwordZx(ptr, 0, d, s) << BfHalfwordRx(0, d, s)) |    \
  565.         (BfHalfwordZx(ptr, 1, d, s) >> BfHalfwordQx(1, d, s))))
  566.  
  567. #define Bf_WordGet(ptr, d, s)                     \
  568.     ((BfWordRx(0, d, s) == 0) ?                 \
  569.     (BfWordZx(ptr, 0, d, s) >> BfWordQx(0, d, s)) :     \
  570.     ((BfWordZx(ptr, 0, d, s) << BfWordRx(0, d, s)) |    \
  571.         (BfWordZx(ptr, 1, d, s) >> BfWordQx(1, d, s))))
  572.  
  573. #endif /* _BF */
  574.  
  575.